/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ChateoController;

import java.io.File;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import ChateoFacadeGUI.FacadeGUI;
import java.util.ArrayList;
import javafx.application.Platform;

/**
 * FXML Controller class
 *
 *
 * @author olga
 * @author adrian
 */
public class ChatViewController implements Initializable {

    @FXML
    private ListView<User> userList;
    @FXML
    private TextArea messagePanel;
    @FXML
    private TextArea historicTextArea;
    @FXML
    private VBox mainView;
    @FXML
    private VBox connectionView;
    @FXML
    private TextField login;
    @FXML
    private Button connect;
    @FXML
    private Button disconnect;
    @FXML
    private VBox root;
    @FXML
    private Label hiLabel;
    @FXML
    private TextArea writeMsgBox;
    @FXML
    private Button sendMsg;
    @FXML
    private Button sendFile;

    /**
     * The list of users where each user is defined by an id you can find in its
     * own class
     */
    private ObservableList<User> allUsers = FXCollections.observableArrayList();

    /**
     * The debugging state will provide some more verbose
     */
    private static boolean debug = true;

    /**
     * The default login of the local user
     */
    private String myLogin = "toto";

    private User localUser;

    /**
     * IDs for a user
     */
    InetAddress addr;
    String username;

    /**
     *   The GUI facade
     */
    private FacadeGUI facadegui = Controller.getFacadegui();
    //Port : STATIC

    /**
     * Initializes the controller class.
     * @param url is the location used to resolve relative paths for the root
     * object, or
     * <tt>null</tt> if the location is not known.
     * @param rb represents resources used to localize the root object, or
     * <tt>null</tt> if the root object was not localized.
     */
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {

        allUsers = userList.getItems();
        userList.getItems().setAll(allUsers);
        setOnConnection();
        setOnUserSelected();
        setOnMessageToSend();
        setOnFileToSend();
        showLoginPage();
        setOnDisonnection();

    }
    
    /**
     * This method is aimed in displaying the authentication page
     */

    private void showLoginPage() {
        root.getChildren().setAll(connectionView);

    }
    
    /**
     * This method is aimed in displaying the page with the CHAT in itself page
     */

    private void showMainView() {
        root.getChildren().setAll(mainView);
        hiLabel.setText("Hola " + myLogin + "!");
    }

    /**
     * This method is aimed in displaying the selected user's messages
     * in the Message textArea
     * @param selectedUser is the user selected from the userList
     */
    private void onUserSelected(User selectedUser) {
        /**
         * display the user message
         */
        String display = "";
		//facadegui.getMessages(user);

        for (ChatMessage msg : facadegui.getMessages(selectedUser)) {
            display += msg + "\n";
        }
        messagePanel.setText(display);
        if (Controller.DebugMode()) {
            System.out.println(display);
        }

    }

    /**
     * This method is aimed in executing the connection after clicking on the connec button
     * 
     */
    private void setOnConnection() {
        connect.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent t) {
                //try {
                //Controller.setFacadeni(new FacadeNI(Controller.getCentralController(), Controller.getPort()));
                myLogin = login.getText();
                final String tmp_myLogin = myLogin;

                    //localUser = new User(InetAddress.getLocalHost(), myLogin);
                //Controller.getCentralController().connect();
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            if (Controller.DebugMode()) {
                                System.out.println("START CONNEXION");
                            }
                            new FacadeGUI().processConneccion(tmp_myLogin, 2014);

                        } /*catch (NullPointerException ex) {
                         Logger.getLogger(ChatViewController.class.getName()).log(Level.SEVERE, null, ex);
                         }*/ catch (SocketException ex) {
                            Logger.getLogger(ChatViewController.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (UnknownHostException ex) {
                            Logger.getLogger(ChatViewController.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                });
                showMainView();
                /*} catch (UnknownHostException ex) {
                 Logger.getLogger(ChatViewController.class.getName()).log(Level.SEVERE, null, ex);
                 } catch (SocketException ex) {
                 Logger.getLogger(ChatViewController.class.getName()).log(Level.SEVERE, null, ex);
                 }*/
            }
        });
    }

    /**
     * This method is aimed in executing the action of disconnection after 
     * clicking on the disconnect button
     */
    private void setOnDisonnection() {
        disconnect.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent t) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            facadegui.processDisconneccion();

                        } catch (UnknownHostException ex) {
                            Logger.getLogger(ChatViewController.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (SocketException ex) {
                            Logger.getLogger(ChatViewController.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                });
                showLoginPage();
                System.exit(0);
            }
        });

    }
    
    /**
     * This method is aimed in executing the action after selecting a user in the userList
     */

    private void setOnUserSelected() {
        userList.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<User>() {

            @Override
            public void changed(ObservableValue<? extends User> ov, User t, User t1) {
                onUserSelected(userList.getSelectionModel().getSelectedItem());
            }

        });
    }

    /**
     * This method is aimed in executing the disconnection after clicking the exit icon
     * @throws UnknownHostException if the host in unknown
     * @throws SocketException if there's a problem with the socket
     */
    public void onExit() throws UnknownHostException, SocketException {
        facadegui.processDisconneccion();

    }
    
    /**
     * This method is aimed in executing the message sending after clicking sendMessage button
     * 
     */

    private void setOnMessageToSend() {
        sendMsg.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent t) {

                final User dest = userList.getSelectionModel().getSelectedItem();
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            facadegui.sendPrivateMessage(dest, writeMsgBox.getText());
                            if (Controller.DebugMode()) {
                                System.out.println("START MESSAGE SENDING");
                            }
                        } catch (SocketException ex) {
                            Logger.getLogger(ChatViewController.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (UnknownHostException ex) {
                            Logger.getLogger(ChatViewController.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                });
                ChatMessage msg = new ChatMessage(writeMsgBox.getText(), localUser, dest, true);
                messagePanel.appendText(msg.toString() + "\n");
                writeMsgBox.setText("");
            }
        });
    }
    
    /**
     * This method is aimed in executing the file sending after clicking sendFile button
     */

    private void setOnFileToSend() {
        sendFile.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent t) {
                FileChooser chooser = new FileChooser();
                final File selectedFile = chooser.showOpenDialog(null);
                if (selectedFile != null) {
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            facadegui.sendFile(selectedFile, userList.getSelectionModel().getSelectedItem());
                        }
                    });
                }
            }

        });
    }

    /**
     * 
     * @param userMessages is the messages received from a user
     */
    public void updateMessagesOnSend(ArrayList<ChatMessage> userMessages) {
        String display = "";
        //facadegui.getMessages(user);
        for (ChatMessage msg : userMessages) {
            display += msg + "\n";
        }
        messagePanel.setText(display);
        if (Controller.DebugMode()) {
            System.out.println(display);
        }

    }
    /**
     * 
     * @param userMessages the messages received from a certain user
     * @param user is the sender of the receeived message
     */

    public void updateMessagesOnReceive(ArrayList<ChatMessage> userMessages, User user) {

        if (userList.getSelectionModel().getSelectedItem() == user) {
            updateMessagesOnSend(userMessages);
        } else {
            //TODO : CHANGE COLOR OF USER
        }

    }

    /**
     * 
     * @param userListIncomming the list of all the connected users
     */
    public void updateUserList(UsersList userListIncomming) {
        ObservableList<User> allUsers1 = FXCollections.observableArrayList(userListIncomming);
        userList.getItems().setAll(allUsers1);

    }

}
